<?php

namespace app\api\controller;

use app\admin\model\ClassAddress;
use app\admin\model\Club;
use app\admin\model\ClubDtl;
use app\admin\model\Order;
use app\admin\model\OrderClassHours;
use app\admin\model\TeacherClassDtl;
use app\admin\model\TeacherSubscribe;
use app\common\controller\Api;
use app\common\model\Test;
use think\Config;
use WeChatPay\Builder;
use WeChatPay\Crypto\AesGcm;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
use WeChatPay\Util\PemUtil;

/**
 * 订单接口
 */
class Orders extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = '*';

    public function _initialize()
    {
        parent::_initialize();
    }

    //下单下拉
    public function order_pull(){
        $params = $this->request->param();
//        if(!isset($params['user_id'])||!$params['user_id']){
//            $this->error('教师用户id必传');
//        }
        if(!isset($params['teacher_detail_id'])||!$params['teacher_detail_id']){
            $this->error('教师课程id必传');
        }
        $user = $this->auth->getUser();
        if(!isset($user['id'])||!$user['id']){
            $this->error('当前登录用户不存在');
        }
        $identity_info = \app\admin\model\TeacherDetail::where(['id'=>$params['teacher_detail_id']])->with(['identity','clubDtlS'])->find();
        if(!$identity_info){
            $this->error('教师不存在');
        }
        $address = ClassAddress::where(['user_id'=>$user['id'],'opt_for'=>1])->find();
        $data = [];
        //教师数据
        $teacher = [];
        $teacher['name'] = $identity_info['identity']['name'];
        $teacher['club_dtl_name'] = $identity_info['club_dtl_s']['name'];
        $teacher['stage'] = isset($identity_info['club_dtl_s']) ? $identity_info['club_dtl_s']['stage'] : '';
        $teacher['grade'] = isset($identity_info['club_dtl_s']) ? $identity_info['club_dtl_s']['grade'] : '';
        $teacher['appointment_time_week'] = $identity_info['identity']['appointment_time_week'];
        $teacher['appointment_time'] = $identity_info['identity']['appointment_time'];
        $teacher['hourly_rate'] = $identity_info['hourly_rate'];
        $teacher['address_id'] = isset($address['id']) ? $address['id'] : 0;
        $teacher['address_name'] = isset($address['detail']) ? $address['detail'] : '';
        $teacher['address_all'] = isset($address['detail']) ? $address['school'].'-'.$address['detail'] : '';
        if(!$identity_info['course_duration']){
            $defaultDuration = Config::get('course.default_course_duration', '');
            $teacher['course_duration'] = $defaultDuration ? $defaultDuration : 40;
        }else{
            $teacher['course_duration'] = (int)$identity_info['course_duration'];
        }
        $week = explode(',',$identity_info['identity']['appointment_time_week']);
        $data['teacher'] = $teacher;
        $data['sign_type'] = ['短期','长期'];

        $identity_info_model = new \app\admin\model\IdentityInfo();
        $week_list_name = $identity_info_model->getWeekNameList();
        $week_num = '';
        $week_arr = [];
        $week_arr_name = [];
        foreach ($week as $k=>$v){
            $num = isset($week_list_name[$v]) ? $week_list_name[$v].',' : '';
            $week_num .= $num;
            $key = isset($week_list_name[$v]) ? $week_list_name[$v] : '';
            $week_arr[$k] = $key;
            $week_arr_name[$key] = $v;
        }
        $data['teacher_appointment_week_num'] = trim($week_num,',');
        $data['teacher_appointment_week_arr'] = $week_arr;
        $data['teacher_appointment_week_arr_name'] = $week_arr_name;

        $data['semester_arr'] = [
            '1'=>'一学期',
            '2'=>'两学期',
            '3'=>'三学期',
            '4'=>'四学期',
            '5'=>'五学期',
            '6'=>'六学期',
        ];

        $this->success('下单下拉',$data);
    }


    function isTimeBetween($checkTime, $startTime, $endTime) {
        $checkTime = trim($checkTime);
        $startTime = trim($startTime);
        $endTime = trim($endTime);
        $check = \DateTime::createFromFormat('H:i', $checkTime);
        $start = \DateTime::createFromFormat('H:i', $startTime);
        $end = \DateTime::createFromFormat('H:i', $endTime);

        if ($check >= $start && $check <= $end) {
            return true;
        }
        return false;
    }

    /**
     * 安全时间加法（禁止跨天）
     * @param string $time 输入时间（格式: H:i）
     * @param int $minutes 要添加的分钟数（支持负数）
     * @return string|false 成功返回时间，失败返回false
     */
    function safeTimeAdd($time, $minutes) {
        $time = trim($time);
        $dt = \DateTime::createFromFormat('H:i', $time);
        if (!$dt) return false;

        $dt->add(new \DateInterval('PT' . abs($minutes) . 'M'));
        if ($minutes < 0) {
            $dt->sub(new \DateInterval('PT' . abs($minutes) . 'M'));
        }

        $originalDay = \DateTime::createFromFormat('H:i', $time)->format('Y-m-d');
        return ($dt->format('Y-m-d') === $originalDay)
            ? $dt->format('H:i')
            : false;
    }

    function numberToChinese($number) {
        $chineseMap = [
            1 => '一',
            2 => '二',
            3 => '三',
            4 => '四',
            5 => '五',
            6 => '六',
            7 => '天', // 7 改为 "天"
        ];

        return $chineseMap[$number] ?? $number; // 如果不在映射表，返回原数字
    }
    //下单(废弃)
    public function add_order(){
        $params = $this->request->param();
        if(!isset($params['user_id'])||!$params['user_id']){
            $this->error('教师用户id必传');
        }
        $identity_info = \app\admin\model\IdentityInfo::where(['user_id'=>$params['user_id'],'identity_type'=>'教师'])->with(['clubDtlS'])->find();
        if(!$identity_info){
            $this->error('教师不存在');
        }

//        $week = explode(',',$identity_info['appointment_time_week']);
        $week = TeacherSubscribe::where(['teacher_id'=>$params['user_id'],'class_id'=>0])->column('week');

        $time = explode('-',$identity_info['appointment_time']);
        $user = $this->auth->getUser();
        if($user['identity_type'] != '校方'){
            $this->error('当前身份不可下单');
        }
        $identity_info_model = new \app\admin\model\IdentityInfo();
        $week_list_name = $identity_info_model->getWeekList();
        $week_arr = [];
        foreach ($week as $k=>$v){
            $key = isset($week_list_name[$v]) ? $week_list_name[$v] : '';
            $week_arr[$k] = $key;
        }
        $data['teacher_appointment_week_arr'] = $week_arr;
        if(!isset($user['id'])||!$user['id']){
            $this->error('当前登录用户不存在');
        }
        if(!isset($params['address_id'])||!$params['address_id']){
            $this->error('地址必传');
        }
        if(!isset($params['sign_type'])||!$params['sign_type']){
            $this->error('签约类型必传');
        }
        if(!isset($params['data'])||!$params['data']){
            $this->error('签约数据必传');
        }

        $class_num_all = 0;
        if(is_array($params['data'])){
            $data = $params['data'];
        }else{
            //php中参数有双引号 会自动转换
            $params['data'] = htmlspecialchars_decode($params['data'], ENT_QUOTES);
            $data = json_decode($params['data'],true);
        }
        $res_date_time = [];
        switch ($params['sign_type']){
            case '短期':
                foreach ($data as $k=>$v){
                    if(!isset($v['class_date'])||!$v['class_date']){
                        $this->error('上课时间必传');
                    }
                    if(!isset($v['class_start_time'])||!$v['class_start_time']){
                        $this->error('开始时间必传');
                    }
                    if(!isset($v['class_num'])||!$v['class_num']){
                        $this->error('课时必传');
                    }
                    $inputDate = $v['class_date'];

                    $weekday = date('N', strtotime($inputDate));
                    $res_date_time[$k] = '周'.$this->numberToChinese($weekday);
                    if (!in_array($weekday, $week)) {
                        $this->error('周'.$this->numberToChinese($weekday).'不在可约时间');
                    }
                    if($v['class_num']>6){
                        $this->error('单次上课最大6课时');
                    }
                    if(isset($time[0])&&$time[0]&&isset($time[1])&&$time[1]){
                        $add_time = precisionRestore($v['class_num'],'40','乘法');//..
                        $end_time = $this->safeTimeAdd($v['class_start_time'],$add_time);
                        if(!$end_time){
                            $this->error('课程开始时间加上课时不可跨天');
                        }
                        $result = $this->isTimeBetween($v['class_start_time'], $time[0], $time[1]);
                        if($result == false){
                            $this->error('课程开始时间不在服务时间内');
                        }
                        $result = $this->isTimeBetween($end_time, $time[0], $time[1]);
                        if($result == false){
                            $this->error('课程结束时间不在服务时间内');
                        }
                    }
                    //总课时
                    $class_num_all = precisionRestore($v['class_num'],$class_num_all,'加法');
                }
                $asd = count($res_date_time) + 1;
                $res_date_time[$asd] = $class_num_all.'课时';
                break;
            case '长期':
                if(!isset($data['semester'])||!$data['semester']){
                    $this->error('学期必传');
                }
                if(!isset($data['semester_hours'])||!$data['semester_hours']){
                    $this->error('总课时必传');
                }
                $res_date_time[0] = $data['semester'];
                $res_date_time[1] = $data['semester_hours'].'课时';
                $class_num_all = $data['semester_hours'];
                break;
            default:
                $this->error('非法参数');
                break;
        }

        //计算金额
        $money_all = precisionRestore($identity_info['hourly_rate'],$class_num_all,'乘法');


        $add_order = [];
        $add_order['order_no'] = Order::get_order_no($user['id']);//订单编号
        $add_order['money'] = (double)$money_all;//金额
        $add_order['pay_status'] = 1;//订单状态 1待支付 2已支付 3已退款
        $add_order['addtime'] = date('Y-m-d H:i:s');//创建时间
//        $add_order['sanfang'] = '';//三方单号
        $add_order['type'] = '';//支付方式
        $add_order['remark'] = isset($params['remark']) ? $params['remark'] : '';//订单备注
        if($user['identity_type']){
            $where = ['identity_type'=>$user['identity_type'],'user_id'=>$user['id']];
        }else{
            $where = ['user_id'=>$user['id']];
        }
        $identity_info_user = \app\admin\model\IdentityInfo::where($where)->find();
        $add_order['identity_id'] = $identity_info_user['id'];//身份id
        $add_order['user_id'] = $user['id'];//用户id
        $add_order['address_id'] = $params['address_id'];//上课地址id
        $teacher = [];
        $teacher['name'] = $identity_info['name'];
        $club_dtl = ClubDtl::where(['id'=>$identity_info['club_two_id']])->find();
        $teacher['club_two'] = $club_dtl['name'];
        $teacher['appointment_time'] = $identity_info['appointment_time'];
        $teacher['hourly_rate'] = $identity_info['hourly_rate'];
        $add_order['info'] = json_encode($teacher);//教师信息
        $add_order['sign_type'] = $params['sign_type'];//签约类型(长期，短期)
        $add_order['teacher_id'] = $params['user_id'];//教师用户id
        $order_id = Order::insertGetId($add_order);


        if(!$order_id){
            $this->error('订单创建失败');
        }
        if($params['sign_type'] == '长期'){
            // 处理学期字段，将中文转换为数字
            $semester = $data['semester'];
            if(is_string($semester) && !is_numeric($semester)){
                // 如果是中文，根据学期数组匹配
                $semester_arr = [
                    '一学期' => '1',
                    '两学期' => '2',
                    '三学期' => '3',
                    '四学期' => '4',
                    '五学期' => '5',
                    '六学期' => '6',
                ];
                $semester = isset($semester_arr[$semester]) ? $semester_arr[$semester] : $semester;
            }

            $add_order_class_hours = [];
            $add_order_class_hours['order_id'] = $order_id;//订单id
            $add_order_class_hours['semester'] = $semester;//学期
            $add_order_class_hours['semester_hours'] = $data['semester_hours'];//课时
            $add_order_class_hours['addtime'] = date('Y-m-d H:i:s');//添加时间
            OrderClassHours::insert($add_order_class_hours);
        }
        if($params['sign_type'] == '短期'){
            $add_order_class_hours = [];
            foreach ($data as $k=>$v){
                $add_order_class_hours[$k]['order_id'] = $order_id;//订单id
                $add_order_class_hours[$k]['class_date'] = $v['class_date'];//上课时间
                $add_order_class_hours[$k]['class_start_time'] = $v['class_start_time'];//开始时间
                $add_order_class_hours[$k]['class_num'] = $v['class_num'];//多少课
                $add_order_class_hours[$k]['addtime'] = date('Y-m-d H:i:s');//添加时间
            }
            OrderClassHours::insertAll($add_order_class_hours);
        }

        $res = [];
        $res['club_name'] = $club_dtl['name'];
        $res['teacher_name'] = $identity_info['name'];
        $res_date_time = array_unique($res_date_time);
        $res['appointment'] = implode(',',$res_date_time);
        $address = ClassAddress::where(['id'=>$params['address_id']])->find();
        $res['address_name'] = $address['school'].'-'.$address['detail'];
        $res['money'] = (double)$money_all;
        $res['class_all_num'] = $class_num_all;
        $res['order_id'] = $order_id;
        $this->success('订单创建成功',$res);
    }

    //下单
    public function add_order_new(){
        $params = $this->request->param();
        if(!isset($params['teacher_detail_id'])||!$params['teacher_detail_id']){
            $this->error('教师课程id必传');
        }
        $identity_info = \app\admin\model\TeacherDetail::where(['id'=>$params['teacher_detail_id']])->with(['identity','clubDtlS'])->find();
        if(!$identity_info){
            $this->error('教师不存在');
        }
        if(isset($identity_info['course_duration'])&&$identity_info['course_duration']){
            //当教师课程配置了课程时间 则赋值课程时间
            $duration = $identity_info['course_duration'];
        }else{
            //如果没有配置，则取公共课程时间
            $defaultDuration = Config::get('course.default_course_duration', '');
            $duration = $defaultDuration;
        }
        $params['user_id'] = isset($identity_info['identity']) ? $identity_info['identity']['user_id'] : 0;
        $week = TeacherSubscribe::where(['teacher_id'=>$params['user_id'],'class_id'=>0])->column('week');

        $time = explode('-',$identity_info['identity']['appointment_time']);
        $user = $this->auth->getUser();
        if($user['identity_type'] != '校方'){
            $this->error('当前身份不可下单');
        }
        $identity_info_model = new \app\admin\model\IdentityInfo();
        $week_list_name = $identity_info_model->getWeekList();
        $week_arr = [];
        foreach ($week as $k=>$v){
            $key = isset($week_list_name[$v]) ? $week_list_name[$v] : '';
            $week_arr[$k] = $key;
        }
        $data['teacher_appointment_week_arr'] = $week_arr;
        if(!isset($user['id'])||!$user['id']){
            $this->error('当前登录用户不存在');
        }
        if(!isset($params['address_id'])||!$params['address_id']){
            $this->error('地址必传');
        }
        if(!isset($params['sign_type'])||!$params['sign_type']){
            $this->error('签约类型必传');
        }
        if(!isset($params['data'])||!$params['data']){
            $this->error('签约数据必传');
        }
        if(!isset($params['class_start_time'])||!$params['class_start_time']){
            $this->error('每日开课时间必传');
        }
        $class_num_all = 0;
        if(is_array($params['data'])){
            $data = $params['data'];
        }else{
            //php中参数有双引号 会自动转换
            $params['data'] = htmlspecialchars_decode($params['data'], ENT_QUOTES);
            $data = json_decode($params['data'],true);
        }
        $res_date_time = [];
        $dtl_arr = [];
        $all_class_num = 0;
        switch ($params['sign_type']){
            case '短期':
                foreach ($data as $k=>$v){
                    if(!isset($v['class_date'])||!$v['class_date']){
                        $this->error('上课时间必传');
                    }
                    $v['class_start_time'] = $params['class_start_time'];
                    if(!isset($v['class_num'])||!$v['class_num']){
                        $this->error('课时必传');
                    }
                    $inputDate = $v['class_date'];

                    $weekday = date('N', strtotime($inputDate));
                    $res_date_time[$k] = '周'.$this->numberToChinese($weekday);
                    if (!in_array($weekday, $week)) {
                        $this->error('周'.$this->numberToChinese($weekday).'不在可约时间');
                    }
                    if($v['class_num']>6){
                        $this->error('单次上课最大6课时');
                    }
                    if(isset($time[0])&&$time[0]&&isset($time[1])&&$time[1]){
                        $add_time = precisionRestore($v['class_num'],$duration,'乘法');
                        $end_time = $this->safeTimeAdd($v['class_start_time'],$add_time);
                        if(!$end_time){
                            $this->error('课程开始时间加上课时不可跨天');
                        }
                        $result = $this->isTimeBetween($v['class_start_time'], $time[0], $time[1]);
                        if($result == false){
                            $this->error('课程开始时间不在服务时间内');
                        }
                        $result = $this->isTimeBetween($end_time, $time[0], $time[1]);
                        if($result == false){
                            $this->error('课程结束时间不在服务时间内');
                        }
                    }
                    //总课时
                    $class_num_all = precisionRestore($v['class_num'],$class_num_all,'加法');
                }
                $asd = count($res_date_time) + 1;
                $res_date_time[$asd] = $class_num_all.'课时';
                break;
            case '长期':
                if(!isset($params['semester'])||!$params['semester']){
                    $this->error('学期必传');
                }
                if(!isset($params['semester_hours'])||!$params['semester_hours']){
                    $this->error('总课时必传');
                }
                if(!isset($params['week_num'])||!$params['week_num']){
                    $this->error('周数必传');
                }
                if(!isset($params['start_date'])||!$params['start_date']){
                    $this->error('课程开始时间');
                }
                $arr_week = [];
                foreach ($data as $k=>$v){
                    if(!isset($v['class_date'])||!$v['class_date']){
                        $this->error('周必传');
                    }
                    $arr_week[$k] = $v['class_date'];
                    if(!isset($v['class_num'])||!$v['class_num']){
                        $this->error('课时必传');
                    }
                    $v['status'] = 1;
                    $v['time_start'] = $params['class_start_time'];
                    $weekday = $week_list_name[$v['class_date']];//长期默认周 传过来的是数字
                    //判断日期是否在可约范围内，判断上课时间，判断课时
                    if (!in_array($weekday, $week_arr)) {
                        $this->error($weekday.'不在可约时间');
//                        $this->error('周'.TeacherClassDtl::numberToChinese($weekday).'不在可约时间');
                    }
                    if($v['class_num']>6){
                        $this->error('单次上课最大6课时');
                    }
                    if(isset($time[0])&&$time[0]&&isset($time[1])&&$time[1]){
                        $add_time = precisionRestore($v['class_num'],$duration,'乘法');
                        $end_time = $this->safeTimeAdd($v['time_start'],$add_time);
                        if(!$end_time){
                            $this->error('课程开始时间加上课时不可跨天');
                        }
                        $result = $this->isTimeBetween($v['time_start'], $time[0], $time[1]);
                        if($result == false){
                            $this->error('课程开始时间不在服务时间内');
                        }
                        $result = $this->isTimeBetween($end_time, $time[0], $time[1]);
                        if($result == false){
                            $this->error('课程结束时间不在服务时间内');
                        }
                    }
//                    $week_date = '周'.TeacherClassDtl::numberToChinese($weekday);
                    $week_date = $weekday;
                    $dtl_arr[$k]['semester'] = $params['semester'];//学期
                    $dtl_arr[$k]['semester_hours'] = $params['semester_hours'];//课时
                    $dtl_arr[$k]['week_num'] = $params['week_num'];//周期
                    $dtl_arr[$k]['class_date'] = $week_date;//日/周
                    $dtl_arr[$k]['class_start_time'] = $v['time_start'];//开始时间
                    $dtl_arr[$k]['class_num'] = $v['class_num'];//课时
                    $dtl_arr[$k]['start_date'] = $params['start_date'];//课程开始时间
                    $all_class_num = precisionRestore($v['class_num'],$all_class_num,'加法');
                }

                $hasDuplicate = count($arr_week) !== count(array_unique($arr_week));
                if($hasDuplicate == true){
                    $this->error('不可设置相同的周');
                }
                $count = TeacherSubscribe::where(['teacher_id'=>$params['user_id']])->where('class_id >0')->whereIn('week',array_unique($arr_week))->count();
                if($count>0){
                    $this->error('存在不可配置的可约时间');
                }
                $res_date_time[0] = $params['semester'];
                $res_date_time[1] = $params['semester_hours'].'课时';
                $class_num_all = $params['semester_hours'];
                break;
            default:
                $this->error('非法参数');
                break;
        }

        //计算金额
        $money_all = precisionRestore($identity_info['hourly_rate'],$class_num_all,'乘法');


        $add_order = [];
        $add_order['order_no'] = Order::get_order_no($user['id']);//订单编号
        $add_order['money'] = (double)$money_all;//金额
        $add_order['pay_status'] = 1;//订单状态 1待支付 2已支付 3已退款
        $add_order['addtime'] = date('Y-m-d H:i:s');//创建时间
//        $add_order['sanfang'] = '';//三方单号
        $add_order['type'] = '';//支付方式
        $add_order['remark'] = isset($params['remark']) ? $params['remark'] : '';//订单备注
        if($user['identity_type']){
            $where = ['identity_type'=>$user['identity_type'],'user_id'=>$user['id']];
        }else{
            $where = ['user_id'=>$user['id']];
        }
        $identity_info_user = \app\admin\model\IdentityInfo::where($where)->find();
        $add_order['identity_id'] = $identity_info_user['id'];//身份id
        $add_order['user_id'] = $user['id'];//用户id
        $add_order['address_id'] = $params['address_id'];//上课地址id
        $teacher = [];
        $teacher['name'] = $identity_info['identity']['name'];
        $club_dtl = ClubDtl::where(['id'=>$identity_info['club_two_id']])->find();
        $teacher['club_two'] = $club_dtl['name'];
        $teacher['appointment_time'] = $identity_info['identity']['appointment_time'];
        $teacher['hourly_rate'] = $identity_info['hourly_rate'];
        $add_order['info'] = json_encode($teacher);//教师信息
        $add_order['sign_type'] = $params['sign_type'];//签约类型(长期，短期)
        $add_order['teacher_id'] = $params['user_id'];//教师用户id
        $add_order['teacher_detail_id'] = $params['teacher_detail_id'];//教师用户id
        $order_id = Order::insertGetId($add_order);


        if(!$order_id){
            $this->error('订单创建失败');
        }
        if($params['sign_type'] == '长期'){
            // 处理学期字段，将中文转换为数字
            $semester = $params['semester'];
            if(is_string($semester) && !is_numeric($semester)){
                // 如果是中文，根据学期数组匹配
                $semester_arr = [
                    '一学期' => '1',
                    '两学期' => '2',
                    '三学期' => '3',
                    '四学期' => '4',
                    '五学期' => '5',
                    '六学期' => '6',
                ];
                $semester = isset($semester_arr[$semester]) ? $semester_arr[$semester] : $semester;
            }
            $add_order_class_hours = [];
            foreach ($dtl_arr as $k=>$v){
                $add_order_class_hours[$k]['order_id'] = $order_id;//订单id
                $add_order_class_hours[$k]['semester'] = $semester;//学期
                $add_order_class_hours[$k]['semester_hours'] = $v['semester_hours'];//课时
                $add_order_class_hours[$k]['week_num'] = $v['week_num'];//周期
                $add_order_class_hours[$k]['class_date'] = $v['class_date'];//日/周
                $add_order_class_hours[$k]['class_start_time'] = $v['class_start_time'];//开始时间
                $add_order_class_hours[$k]['class_num'] = $v['class_num'];//课时
                $add_order_class_hours[$k]['start_date'] = $v['start_date'];//课程开始时间
                $add_order_class_hours[$k]['addtime'] = date('Y-m-d H:i:s');//添加时间
            }
            OrderClassHours::insertAll($add_order_class_hours);
        }
        if($params['sign_type'] == '短期'){
            $add_order_class_hours = [];
            foreach ($data as $k=>$v){
                $add_order_class_hours[$k]['order_id'] = $order_id;//订单id
                $add_order_class_hours[$k]['class_date'] = $v['class_date'];//上课时间
                $add_order_class_hours[$k]['class_start_time'] = $params['class_start_time'];//开始时间
                $add_order_class_hours[$k]['class_num'] = $v['class_num'];//多少课
                $add_order_class_hours[$k]['addtime'] = date('Y-m-d H:i:s');//添加时间
            }
            OrderClassHours::insertAll($add_order_class_hours);
        }

        $res = [];
        $res['club_name'] = $club_dtl['name'];
        $res['teacher_name'] = $identity_info['identity']['name'];
        $res_date_time = array_unique($res_date_time);
        $res['appointment'] = implode(',',$res_date_time);
        $address = ClassAddress::where(['id'=>$params['address_id']])->find();
        $res['address_name'] = $address['school'].'-'.$address['detail'];
        $res['money'] = (double)$money_all;
        $res['class_all_num'] = $class_num_all;
        $res['order_id'] = $order_id;
        $this->success('订单创建成功',$res);
    }

    //计算总课时
    public function calculate_semester_hours(){
        $params = $this->request->param();
        if(!isset($params['data'])||!$params['data']){
            $this->error('签约数据必传');
        }
        if(!isset($params['week_num'])||!$params['week_num']){
            $this->error('周数必传');
        }
        if(is_array($params['data'])){
            $data = $params['data'];
        }else{
            //php中参数有双引号 会自动转换
            $params['data'] = htmlspecialchars_decode($params['data'], ENT_QUOTES);
            $data = json_decode($params['data'],true);
        }

        $class_num = 0;
        foreach ($data as $k=>$v){
            $class_num = precisionRestore($v['class_num'],$class_num,'加法');
        }
        $all_num = precisionRestore($params['week_num'],$class_num,'乘法');
        $this->success('计算总课时',$all_num);
    }

    //订单支付
    public function pay_order(){
        $params = $this->request->param();
        if(!isset($params['order_id'])||!$params['order_id']){
            $this->error('订单id必传');
        }
        if(!isset($params['club_name'])||!$params['club_name']){
            $this->error('社团名称必传');
        }
        if(!isset($params['teacher_name'])||!$params['teacher_name']){
            $this->error('教师名称必传');
        }
        if(!isset($params['class_all_num'])||!$params['class_all_num']){
            $this->error('总课时必传');
        }
        if(!isset($params['type'])||!$params['type']){
            $this->error('支付方式');
        }
        $user = $this->auth->getUser();
        if(!isset($user['id'])||!$user['id']){
            $this->error('当前登录用户不存在');
        }
        $order = Order::where(['id'=>$params['order_id']])->find();
        if(!$order||$order['pay_status']!=1){
            $this->error('订单异常，请重新下单');
        }
        $money = (double)$order['money'];
        $description = $params['club_name'].'-'.$params['teacher_name'].'-'.$params['class_all_num'].'课时';
        $res = [];
        switch ($params['type']){
            case '微信':
                $payData = $this->wx_pay($money,$order['order_no'],$description);
                $pay = json_decode($payData,true);
                if (!$pay) {
                    $this->error("创建订单失败，请返回重试");
                }
                if($pay['prepay_id']){
                    $res['type'] = 'app微信支付';
                    $res['prepay_id'] = $pay['prepay_id'];
                    $res['pay_status'] = 1;
                }
                break;
            case '线下支付':
                //直接走支付完成方法
                $res['type'] = '线下支付';
                $res['pay_status'] = 2;
                if(isset($params['is_new'])&&$params['is_new']==1){
                    $pay_success = Order::pay_success_new($order['order_no'],'','线下支付');
                }else{
                    $pay_success = Order::pay_success($order['order_no'],'','线下支付');
                }
                if($pay_success['code'] == 0){
                    $this->error($pay_success['msg']);
                }
                break;
            default:
                $this->error('不支持的支付方式');
                break;
        }
        $this->success('订单支付',$res);
    }

    //订单支付状态
    public function get_order_pay_status(){
        $params = $this->request->param();
        if(!isset($params['order_id'])||!$params['order_id']){
            $this->error('订单id必传');
        }
        $order = Order::where(['id'=>$params['order_id']])->find();
        switch ($order['pay_status']){
            case 1:
                $this->success('支付状态','待支付');
                break;
            case 2:
                $this->success('支付状态','已支付');
                break;
            case 3:
                $this->success('支付状态','已退款');
                break;
            default:
                $this->error('未知状态');
                break;
        }
    }

    //微信支付
    public function wx_pay($money,$order_id,$description='购买课程'){
        $merchantId = '1710092419';
        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyFilePath = 'file:///www/wwwroot/hainan.megmt.com/public/apiclient_key.pem';
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
        // 「商户API证书」的「证书序列号」
        $merchantCertificateSerial = '1F49455BB07F3F1818168E1E21389FA89554968F';
        // 从本地文件中加载「微信支付平台证书」(可使用证书下载工具得到），用来验证微信支付应答的签名
        $platformCertificateFilePath = 'file:///www/wwwroot/hainan.megmt.com/public/wechatpay_77A215B745C4B7817B7DC820BD8AFC579779FB5C.pem';
        $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
        // 从「微信支付平台证书」中获取「证书序列号」
        $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid'      => $merchantId,
            'serial'     => $merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs'      => [
                $platformCertificateSerial => $platformPublicKeyInstance,
            ],
        ]);
        // 以 Native 支付为例，发送请求
        $resp = $instance
            ->chain('v3/pay/transactions/app')
            ->post(['json' => [
                'mchid'        => $merchantId,
                'out_trade_no' => $order_id,
                'appid'        => 'wxf648206ca41b10bc',
                'description'  => $description,
                'notify_url'   => 'http://school.xukebao.cn/index.php/api/demo/wxcallback',
                'amount'       => [
                    'total'    => $money*100,
                    'currency' => 'CNY'
                ],
            ]]);
        return $resp->getBody()->getContents();
    }

    //微信退款
    public function wx_refund(){
        $all = $this->request->post();
        $order_no = $all['order_no'];
        $order = Order::where(['order_no'=>$order_no])->find();

        $merchantId = '1710092419';
        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyFilePath = 'file:///www/wwwroot/hainan.megmt.com/public/apiclient_key.pem';
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
        // 「商户API证书」的「证书序列号」
        $merchantCertificateSerial = '1F49455BB07F3F1818168E1E21389FA89554968F';
        // 从本地文件中加载「微信支付平台证书」(可使用证书下载工具得到），用来验证微信支付应答的签名
        $platformCertificateFilePath = 'file:///www/wwwroot/hainan.megmt.com/public/wechatpay_77A215B745C4B7817B7DC820BD8AFC579779FB5C.pem';
        $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
        // 从「微信支付平台证书」中获取「证书序列号」
        $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid'      => $merchantId,
            'serial'     => $merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs'      => [
                $platformCertificateSerial => $platformPublicKeyInstance,
            ],
        ]);
        $out_refund_no = \app\admin\model\OrderRefunds::getOrderNo();
        $promise = $instance
            ->chain('v3/refund/domestic/refunds')
            ->postAsync([
                'json' => [
                    'out_trade_no' => $order_no,
                    'out_refund_no'  => $out_refund_no,
                    'notify_url'=>'http://school.xukebao.cn/index.php/api/demo/wxrefundcallback',
                    'amount'         => [
                        'refund'   => $order['money']*100,
                        'total'    => $order['money']*100,
                        'currency' => 'CNY',
                    ],
                ],
            ])
            ->then(static function($response) use($out_refund_no,$order_no,$order){
                // 正常逻辑回调处理
                $res = $response->getBody()->getContents();
                $res_data = json_decode($res,true);
                \app\admin\model\OrderRefunds::create(['title'=>'微信退款','out_order_id'=>$out_refund_no,'order_id'=>$order_no,'money'=>$order['money'],'status'=>$res_data['status'],'addtime'=>date('Y-m-d H:i:s'),'msg'=>'']);
                return $response;
            })
            ->otherwise(static function($e) {
                // 异常错误处理
                echo $e->getMessage(), PHP_EOL;
                if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                    $r = $e->getResponse();
                    echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                    echo (string) $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;
                }
                echo $e->getTraceAsString(), PHP_EOL;
            });
        // 同步等待
        $promise->wait();

        $this->success("成功", '成功');
    }
}
